home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_10 / milam / xdate < prev   
Text File  |  1994-07-12  |  10KB  |  321 lines

  1.  
  2.  
  3. /***************************************************************/
  4. /*            Extended Date Functions                          */
  5. /*                                                             */
  6. /*            (c) Copyright 1993 by Stan Milam                 */
  7. /***************************************************************/
  8.  
  9. date_t to_date( char *string, int type ) {
  10.  
  11.     date_t rv;
  12.     struct dt dt = { 0, 0, 0, 0, 0, 0 };
  13.     int    len, i, mday, yday, month, year;
  14.     char   wrkbuf[16], **months = full_month;
  15.  
  16.     year = month = yday = mday = 0;
  17.     switch ( type ) {
  18.  
  19.         case DDMMCCYY :
  20.             i = sscanf(string, "%2d%2d%4d", &mday, &month, 
  21.                        &year);
  22.             if ( i != 3 ) return (date_t) -1L;
  23.             month--;
  24.             break;
  25.  
  26.         case MMDDCCYY :
  27.             i = sscanf(string, "%2d%2d%4d", &month, &mday, 
  28.                        &year);
  29.             if ( i != 3 ) return (date_t) -1L;
  30.             month--;
  31.             break;
  32.  
  33.         case GREGDATE :
  34.             i = sscanf(string, "%d%*c%d%*c%d", &month, &mday, 
  35.                        &year);
  36.             if ( i != 3 ) return (date_t) -1L;
  37.             month--;
  38.             break;
  39.  
  40.         case MILDATE :
  41.             i = sscanf(string,"%d%*c%d%*c%d",&mday, &month, &year);
  42.             if ( i != 3) return (date_t) -1L;
  43.             month--;
  44.             break;
  45.  
  46.         case SPELLDATE :
  47.             i = sscanf(string, "%d%*c%3c%*c%d", &mday, wrkbuf, 
  48.                        &year);
  49.             if (i != 3) return (date_t) -1L;
  50.             for (month = 0, len = 3; month < 12; month++) {
  51.                 if ( compare( wrkbuf, months[month], len ) == 0 )
  52.                     break;
  53.             }
  54.             if ( month == 12 ) return (date_t) -1;
  55.             break;
  56.  
  57.         case JULDATE :
  58.             len = strlen( string );
  59.             if ( len == 5 || len == 7 ) {
  60.                 len -= 3;
  61.                 sprintf(wrkbuf, "%%%dd%%%dd", len, 3);
  62.                 i = sscanf(string, wrkbuf, &year, &yday);
  63.                 if ( i != 2 ) return (date_t) -1L;
  64.                 yday--;
  65.             }
  66.             else return (date_t) -1L;
  67.             break;
  68.  
  69.         case SYSDATE :
  70.             len = strlen( string );
  71.             if ( len == 8 || len == 6 ) {
  72.                 len -= 4;
  73.                 sprintf(wrkbuf, "%%%dd%%%dd%%%dd", len, 2, 2);
  74.                 i = sscanf(string, wrkbuf, &year, &month, &mday);
  75.                 if ( i != 3 ) return (date_t) -1L;
  76.                 month--;
  77.             }
  78.             else return ( date_t ) -1L;
  79.             break;
  80.  
  81.         default :
  82.             return (date_t) -1L;
  83.  
  84.     }
  85.  
  86.     /***********************************************************/
  87.     /* If the year is a two digit year, adjust for the century */
  88.     /* change.  Anything less than 80 is considered to be in   */
  89.     /* 21st century.                                           */
  90.     /***********************************************************/
  91.  
  92.     if ( year < 100 )
  93.         year += year < 80 ? 2000 : 1900;
  94.  
  95.     /***********************************************************/
  96.     /* Setup and call mkdate() to get the sequential day number*/
  97.     /***********************************************************/
  98.  
  99.     dt.dt_year = year;
  100.     dt.dt_mday = mday;
  101.     dt.dt_yday = yday;
  102.     dt.dt_month= month;
  103.     rv = mkdate( &dt );
  104.     return rv;
  105. }
  106.  
  107. char *date_to_string(char *buffer, date_t day, int type) {
  108.  
  109.     int    size;
  110.     struct dt *dt;
  111.     char   wrkbuf[25], *format;
  112.  
  113.     wrkbuf[0] = '\0';
  114.     size      = sizeof(wrkbuf);
  115.  
  116.     switch ( type ) {
  117.  
  118.         case GREGDATE  :
  119.             format = "%x";
  120.             break;
  121.  
  122.         case MILDATE   :
  123.             format = "%d/%m/%Y";
  124.             break;
  125.  
  126.         case SPELLDATE :
  127.             format = "%d-%b-%Y";
  128.             break;
  129.  
  130.         case JULDATE   :
  131.             format = "%Y%j";
  132.             break;
  133.  
  134.         case SYSDATE   :
  135.             format = "%Y%m%d";
  136.             break;
  137.  
  138.         case DDMMCCYY  :
  139.             format = "%d%m%Y";
  140.             break;
  141.  
  142.         case MMDDCCYY  :
  143.             format = "%m%d%Y";
  144.             break;
  145.  
  146.         default        :
  147.             format = NULL;
  148.     }
  149.  
  150.     if ( format != NULL ) {
  151.         if (( dt = localdate( &day )) != NULL )
  152.             strfdate(wrkbuf, size, format, dt);
  153.     }
  154.     return (strcpy(buffer, wrkbuf));
  155. }
  156.  
  157. char *to_char(char *buffer, date_t day, int type) {
  158.  
  159.     return date_to_string(buffer, day, type);
  160. }
  161.  
  162. date_t next_day_of_week( date_t value, int day ) {
  163.  
  164.     date_t rv;
  165.     struct dt *dt;
  166.  
  167.     /***********************************************************/
  168.     /* See if we have a valid date value.                      */
  169.     /***********************************************************/
  170.  
  171.     if ( (dt = localdate( &value )) == NULL )
  172.         rv = (date_t) -1L;
  173.     else if ( day < SUNDAY || day > SATURDAY )
  174.         rv = (date_t) -1L;
  175.     else {
  176.         /*******************************************************/
  177.         /* Compute how many days until the next specifed day of*/
  178.         /* the week. Make sure we are within our limits too.   */
  179.         /*******************************************************/
  180.         rv = (date_t) 7 - dt->dt_wday + day;
  181.         if ( rv > (date_t) 7) rv -= (date_t) 7;
  182.         rv = rv + value > MAXDATE ? (date_t) -1L : rv + value;
  183.     }
  184.  
  185.     return rv;
  186. }
  187.  
  188. date_t previous_day_of_week( date_t value, int day ) {
  189.  
  190.     date_t rv;
  191.     struct dt *dt;
  192.  
  193.     /***********************************************************/
  194.     /* Check for a valid date value.                           */
  195.     /***********************************************************/
  196.  
  197.     if ((dt = localdate( &value )) == NULL)
  198.         rv = (date_t) -1L;
  199.     else if ( day < SUNDAY || day > SATURDAY )
  200.         rv = (date_t) -1L;
  201.     else {
  202.         /*******************************************************/
  203.         /* Compute the date value for previous specified day   */
  204.         /* and do sanity check.                                */
  205.         /*******************************************************/
  206.         rv = (date_t) day - dt->dt_wday;
  207.         if ( rv >= (date_t) 0 ) rv -= (date_t) 7L;
  208.         rv += value;
  209.         if ( rv < (date_t) 1L ) rv = (date_t) -1L;
  210.     }
  211.  
  212.     return rv;
  213. }
  214.  
  215. date_t last_day_of_month( date_t value ) {
  216.  
  217.     date_t rv;
  218.     struct dt *dt = localdate( &value );
  219.  
  220.     /***********************************************************/
  221.     /* See if date value was valid.                            */
  222.     /***********************************************************/
  223.  
  224.     if ( dt == NULL )
  225.         rv = (date_t) -1L;
  226.     else {
  227.         /*******************************************************/
  228.         /* Determine last day of the month, compute the diffe- */
  229.         /* rence and add to the date value.                    */
  230.         /*******************************************************/
  231.         rv = month_table[ dt -> dt_month ];
  232.         if ( dt -> dt_month == 1 ) rv += dt -> dt_leap_year;
  233.         rv = rv - dt -> dt_mday + value;
  234.     }
  235.     return rv;
  236. }
  237.  
  238. date_t first_day_of_month( date_t value ) {
  239.  
  240.     date_t rv;
  241.     struct dt *dt = localdate( &value );
  242.  
  243.     rv = ( dt == NULL ) ? -1L : (date_t) 1 - dt -> dt_mday + value;
  244.     return rv;
  245. }
  246.  
  247. date_t compute_date(date_t value, int years, int months, int weeks, int days) {
  248.  
  249.     date_t rv;                         /* Return value */
  250.     int    ld1, ld2;                   /* Last days of months */
  251.     struct dt *wrk;                    /* A date structure */
  252.  
  253.     wrk = localdate( &value );         /* Get a date structure */
  254.     if ( wrk == NULL ) return (date_t) -1L;
  255.  
  256.     /***********************************************************/
  257.     /* Go ahead and compute the weeks and days.                */
  258.     /***********************************************************/
  259.  
  260.     rv = (weeks * 7) + days;
  261.  
  262.     /***********************************************************/
  263.     /* Now compute the months.  We may have to adjust the years*/
  264.     /* value.                                                  */
  265.     /***********************************************************/
  266.  
  267.     if ( months ) {
  268.         if ( abs(months) > 11 ) {
  269.             years += months / 12;
  270.             months = months % 12;
  271.